#include "HalconWidget.h"
#include <QPainter>
#include <QWheelEvent>
#include <QMessageBox>

using namespace HalconCpp;

HalconWidget::HalconWidget(QWidget *parent)
    : QWidget(parent)
    , imageLoaded(false)
    , isDragging(false)
    , zoomFactor(1.0)
    , imageRow1(0), imageCol1(0), imageRow2(512), imageCol2(512)
{
    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_NoSystemBackground);
    setMouseTracking(true);
    setFocusPolicy(Qt::StrongFocus);

    // 设置背景色
    setStyleSheet("background-color: #2b2b2b;");

    initializeHalconWindow();
}

HalconWidget::~HalconWidget()
{
    try {
        if (hWindowID.Length() > 0) {
            CloseWindow(hWindowID);
        }
    } catch (...) {
        // 忽略析构时的异常
    }
}

void HalconWidget::initializeHalconWindow()
{
    try {
        // 获取Qt窗口的系统句柄
        HTuple windowHandle;
        SetWindowAttr("background_color","black");

        // 创建Halcon窗口，绑定到当前Qt控件
        OpenWindow(0, 0, width(), height(),
                   (Hlong)winId(), "visible", "", &hWindowID);

        // 设置窗口属性
        SetWindowAttr("background_color","black");
        SetPart(hWindowID, imageRow1, imageCol1, imageRow2, imageCol2);

    } catch (HException &ex) {
        QMessageBox::critical(this, "Halcon Error",
                              QString("Failed to initialize Halcon window: %1")
                                  .arg(ex.ErrorMessage().Text()));
    }
}

void HalconWidget::displayImage(const HObject &image)
{
    try {
        currentImage = image;
        imageLoaded = true;

        // 获取图像尺寸
        HTuple width, height;
        GetImageSize(image, &width, &height);

        // 设置显示区域为整个图像
        imageRow1 = 0;
        imageCol1 = 0;
        imageRow2 = height - 1;
        imageCol2 = width - 1;

        updateImageDisplay();

    } catch (HException &ex) {

        qDebug()<<"Display Error: Failed to display image "<<ex.ErrorMessage().Text();

        // QMessageBox::warning(this, "Display Error",
        //                      QString("Failed to display image: %1")
        //                          .arg(ex.ErrorMessage().Text()));
    }
}

void HalconWidget::clearDisplay()
{
    try {
        ClearWindow(hWindowID);
        imageLoaded = false;
        update();
    } catch (HException &ex) {
        // 处理异常
    }
}

void HalconWidget::fitImageToWindow()
{
    if (!imageLoaded) return;

    try {
        // 获取图像尺寸
        HTuple width, height;
        GetImageSize(currentImage, &width, &height);

        // 计算适合窗口的显示区域
        double widgetAspect = (double)this->width() / this->height();
        double imageAspect = (double)width / height;

        if (widgetAspect > imageAspect) {
            // 窗口更宽，按高度适应
            double displayHeight = height;
            double displayWidth = height * widgetAspect;
            imageRow1 = 0;
            imageCol1 = -(displayWidth - width) / 2;
            imageRow2 = height - 1;
            imageCol2 = width + (displayWidth - width) / 2;
        } else {
            // 窗口更高，按宽度适应
            double displayWidth = width;
            double displayHeight = width / widgetAspect;
            imageRow1 = -(displayHeight - height) / 2;
            imageCol1 = 0;
            imageRow2 = height + (displayHeight - height) / 2;
            imageCol2 = width - 1;
        }

        SetPart(hWindowID, imageRow1, imageCol1, imageRow2, imageCol2);
        updateImageDisplay();

    } catch (HException &ex) {
        QMessageBox::warning(this, "Fit Error",
                             QString("Failed to fit image: %1")
                                 .arg(ex.ErrorMessage().Text()));
    }
}

void HalconWidget::setPart(double row1, double col1, double row2, double col2)
{
    imageRow1 = row1;
    imageCol1 = col1;
    imageRow2 = row2;
    imageCol2 = col2;

    try {
        SetPart(hWindowID, imageRow1, imageCol1, imageRow2, imageCol2);
        updateImageDisplay();
    } catch (HException &ex) {
        // 处理异常
    }
}

void HalconWidget::setZoom(double factor)
{
    if (factor <= 0) return;

    zoomFactor = factor;

    // 计算新的显示区域
    double centerRow = (imageRow1 + imageRow2) / 2;
    double centerCol = (imageCol1 + imageCol2) / 2;
    double height = (imageRow2 - imageRow1) / zoomFactor;
    double width = (imageCol2 - imageCol1) / zoomFactor;

    imageRow1 = centerRow - height / 2;
    imageRow2 = centerRow + height / 2;
    imageCol1 = centerCol - width / 2;
    imageCol2 = centerCol + width / 2;

    setPart(imageRow1, imageCol1, imageRow2, imageCol2);
}

void HalconWidget::zoomIn()
{
    setZoom(zoomFactor * 1.2);
}

void HalconWidget::zoomOut()
{
    setZoom(zoomFactor / 1.2);
}

void HalconWidget::resetZoom()
{
    if (!imageLoaded) return;

    try {
        HTuple width, height;
        GetImageSize(currentImage, &width, &height);

        imageRow1 = 0;
        imageCol1 = 0;
        imageRow2 = height - 1;
        imageCol2 = width - 1;
        zoomFactor = 1.0;

        setPart(imageRow1, imageCol1, imageRow2, imageCol2);
    } catch (HException &ex) {
        // 处理异常
    }
}

void HalconWidget::onDisplayImage(const QString& filename)
{
    HObject image;
    ReadImage(&image,filename.toStdString().c_str());
    displayImage(image);
}

void HalconWidget::updateImageDisplay()
{
    if (!imageLoaded) return;

    try {
        ClearWindow(hWindowID);
        DispObj(currentImage, hWindowID);
        update();
    } catch (HException &ex) {
        // 处理异常
    }
}

void HalconWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    // Halcon负责绘制图像，Qt只需要绘制背景
    QPainter painter(this);
    painter.fillRect(rect(), QColor("#2b2b2b"));
}

void HalconWidget::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    try {
        if (hWindowID.Length() > 0) {
            // 调整Halcon窗口大小
            SetWindowExtents(hWindowID, 0, 0, width(), height());

            // 重新适应图像
            if (imageLoaded) {
                //fitImageToWindow();
                updateImageDisplay();
            }
        }
    } catch (HException &ex) {
        // 处理异常
    }
}

void HalconWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        lastMousePos = event->pos();
        isDragging = true;
        setCursor(Qt::ClosedHandCursor);
    }

    QWidget::mousePressEvent(event);
}

void HalconWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (isDragging && imageLoaded) {
        QPoint delta = event->pos() - lastMousePos;
        lastMousePos = event->pos();

        // 计算移动距离对应的图像坐标变化
        double moveRow = (imageRow2 - imageRow1) * delta.y() / height();
        double moveCol = (imageCol2 - imageCol1) * delta.x() / width();

        imageRow1 -= moveRow;
        imageRow2 -= moveRow;
        imageCol1 -= moveCol;
        imageCol2 -= moveCol;

        setPart(imageRow1, imageCol1, imageRow2, imageCol2);
    }

    QWidget::mouseMoveEvent(event);
}

void HalconWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isDragging = false;
        setCursor(Qt::ArrowCursor);
    }

    QWidget::mouseReleaseEvent(event);
}

void HalconWidget::wheelEvent(QWheelEvent *event)
{
    if (!imageLoaded) {
        QWidget::wheelEvent(event);
        return;
    }

    QPoint numDegrees = event->angleDelta() / 8;

    if (!numDegrees.isNull()) {
        QPoint numSteps = numDegrees / 15;

        if (numSteps.y() > 0) {
            zoomIn();
        } else {
            zoomOut();
        }
    }

    event->accept();
}
